Skip to content

cmd/loopvec-toolexec: rewrite default builds on darwin, ios, android and windows - #8

Merged
thesyncim merged 4 commits into
masterfrom
toolexec-default-pie
Nov 1, 2026
Merged

thesyncim merged 4 commits into
masterfrom
toolexec-default-pie

Conversation

@thesyncim

@thesyncim thesyncim commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #4.

On macOS the wrapper never rewrites anything. darwin builds PIE by default, the go command passes -shared to every compile, and -shared is on the unsupported list. The same goes for windows, ios and android (they're the targets where internal/platform.DefaultPIE is true). Seven of the eight toolexec scripts fail on macOS because of it.

The concern with -shared is that the nested simd build wouldn't match. But when PIE is the target's default, the nested build is PIE too. So -shared is now accepted when GOOS, which the go command sets for its tools, is one of those four. Anywhere else, an explicit -buildmode=pie is still skipped. toolexec_buildmode_pie.txt covers both sides: a default darwin build is rewritten and prints the same output, and -buildmode=pie on linux is skipped.

toolexec_tests_simd_dependency still fails on macOS, because it reads the parent go command from /proc. I left that alone.

Without this I couldn't use the wrapper on goav1 on a Mac at all.

ubuntu-latest is now ubuntu-26.04, which has no qemu-user-static
package, so every run fails at the install step and skips the arm64
tsvc run, the golden check, fmt and lint. qemu-user ships the static
emulators there; link qemu-aarch64-static to it when the name is
missing, as the Makefile runs that name.
Go tip writes export data in iexport version 4, which encodes float
constants exactly. x/tools v0.51.0, and the v0.52.0 release, read only
up to version 3, so on tip go/packages fails for every package:

  cannot import "math" (unstable iexport format version 4, just rebuild
  compiler and std library), export data is newer version - update tool

and every script that runs loopvec fails in the tip job. x/tools master
reads version 4 (golang/tools@966056e2637c). Update to it until a release
includes it. The pinned toolchain is unaffected.
@thesyncim
thesyncim force-pushed the toolexec-default-pie branch from 141364b to 05b5ea0 Compare October 31, 2026 20:50
go1.27.3 is the latest 1.27 release. Its simd package is the same as
go1.27.1's, so the capability table only changes in its header, and
the -methods crash (golang/go#80657) is still there, as
flag_methods_ice.txt checks. go.mod keeps go 1.27.1: that is the first
release whose simd package loopvec's output compiles against
(go1.27.0's ShiftAllRight takes a uint8).
…and windows

The wrapper leaves a package alone when its compile has -shared, since
the nested build of simd and its dependencies would not match its
objects. But -shared is also how the go command compiles a
position-independent executable, the default build mode on darwin, ios,
android and windows. There every default build was left alone, so
loopvec-toolexec rewrote nothing on macOS, and seven of the toolexec
scripts failed there.

On those targets the nested build is position-independent by default
too, so -shared is accepted. Elsewhere, where -buildmode=pie must be
asked for, it still leaves the package alone, as
toolexec_buildmode_pie.txt checks on linux. The go command sets GOOS for
the tools it runs.
@thesyncim
thesyncim force-pushed the toolexec-default-pie branch from 05b5ea0 to 7f2af16 Compare October 31, 2026 21:50
@thesyncim
thesyncim merged commit 5e414c3 into master Nov 1, 2026
2 checks passed
mauri870 pushed a commit that referenced this pull request Nov 3, 2026
abs_sqrt.txt, activation_temp.txt and invariant_call.txt compare both
builds with testmain/output, which was recorded on amd64. A NaN that an
operation creates (the square root of a negative number, 0 times
infinity) has the sign bit set on amd64 and clear on arm64, so on arm64
the scalar program itself does not match the recording and the scripts
fail before the simd build runs.

The recording is now compared only on amd64. On every target the simd
build is compared with the scalar build of the same machine, which is
the property these scripts check: the rewrite produces the same bits
the scalar loop does there.
mauri870 added a commit that referenced this pull request Nov 3, 2026
The only arm64 coverage in CI was tsvc-test-qemu-arm64, which runs
TestGolden in ./tsvc. The testdata scripts never ran on arm64, so
abs_sqrt.txt, activation_temp.txt and invariant_call.txt compared
arm64 output against an amd64 recording, and nothing caught it until
the suite was run on an M4 (fixed in #8).

This change adds test-qemu-arm64, which runs go test ./... for
GOARCH=arm64 under qemu-aarch64-static, the same way the tsvc target
does. It is make test without -race, which needs cgo. Unlike TestGolden,
the scripts and tsvc's TestCoverage run the arm64 binaries they build,
so the target also needs an aarch64 binfmt handler; on Ubuntu,
installing qemu-user-static registers one. The target is added to ci
and to the workflow, after qemu is installed.
mauri870 added a commit that referenced this pull request Nov 3, 2026
`flag_diff.txt` fails on macOS. The `-d` headers carry `diff`'s
timestamp, and BSD diff prints it differently from GNU diff (no
fractional seconds, no zone). It's the timestamp of a temp file anyway,
so it doesn't tell the reader anything.

This passes `-L path` for both sides (GNU, BSD and busybox diff all have
it), so the headers are just `--- path` / `+++ path` like `gofmt -d`,
and the filename replacement goes away. The four diff scripts now expect
the path alone.

It's one of three small fixes to get the suite passing on macOS, along
with #8 and #9, which I needed while trying loopvec on
[goav1](https://github.com/thesyncim/goav1).

Co-authored-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant